package com.yangcangclub.api.v1.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.yangcangclub.commons.annotation.*;
import com.yangcangclub.commons.config.SysConfig;
import com.yangcangclub.commons.exception.ApolloException;
import com.yangcangclub.commons.result.MessageEnum;
import com.yangcangclub.commons.result.ResultData;
import com.yangcangclub.commons.utils.*;
import com.google.common.collect.Maps;
import com.yangcangclub.pay.tenpay.WeChatConfig;
import com.yangcangclub.user.component.UserComponent;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/yangcangclub/v1/user/*")
public class UserController {

    private static Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    public SysConfig sysConfig;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    UserAuth userAuth;

    @Autowired
    UserComponent userComponent;



    @RequestMapping(value = "/access_token")
    @ResponseBody
    @ApolloSecurity(auth = AuthEnum.USER,limit = 50,time = TimeEnum.MINUTE)
    public ResultData getUserInfo(@GetUser User user,HttpServletResponse response){
        ResultData resultData ;
        try {
            Map<String,String> map= Maps.newHashMap();
            map.put("access_token",user.getAccessToken());
            logger.error("----/getUserInfo, access_token:"+user.getAccessToken());

//            Map<String,String> userInfoMap = BeanMapUtil.convertBean(user);
//            Map<String,Object> userMap = userComponent.getUserInfo(user.getId());
//            if(userMap.containsKey("userInfo")){
//                Map<String,Object> userInfo = (Map<String,Object>)userMap.get("userInfo");
//                userInfoMap.put("user_mark",userInfo.get("user_mark").toString());
//            }

            resultData = new ResultData(MessageEnum.SUCCESS,user);
        }  catch (ApolloException apoEx) {

            resultData=new ResultData(apoEx);
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultData=new ResultData(e);
        }
        return resultData;
    }

    @RequestMapping(value = "/wx/login", method = {RequestMethod.GET})
    public String wxLogin(HttpServletRequest request,HttpServletResponse response,Model model) {

        ResultData resultData = new ResultData();
        resultData.setCode(1000);
        Map<String,Object> data = Maps.newConcurrentMap();
        data.put("accessToken","5270A4C6167249EA9294A346766F7B25");
        data.put("openId","o69NWxBrviZYRWKlsboxbfnZNCoU");
        resultData.setData(data);
        model.addAttribute("resultData",resultData);
        return "index";

//        try {
//            Cookie[] cookies = request.getCookies();
//
//            logger.error("----/wx/login: coming!!");
//            if(cookies != null) {
//                logger.error("----/wx/login: has cookies!!");
//
////                logger.error("2:"+cookies.toString());
//                String accessToken = null;
//                String openId = null;
//                for (int i = 0; i < cookies.length; i++) {
//                    Cookie cookie = cookies[i];
//                    if(StringUtil.isNotEmpty(accessToken)
//                            &&StringUtil.isNotEmpty(openId)) {
//                        break;
//                    }
//                    if ("WX_TICKET_COOKIE_KEY".equals(cookie.getName())) {
//                        accessToken = cookie.getValue();
//                    }
//                    if ("WX_OPENID_COOKIE_KEY".equals(cookie.getName())) {
//                        openId = cookie.getValue();
//                    }
//                }
//                logger.error("----/wx/login value in cookies: accessToken:"+accessToken);
//                logger.error("----/wx/login value in cookies: openId:"+openId);
//
//
//                if(StringUtil.isNotEmpty(accessToken)
//                        &&StringUtil.isNotEmpty(openId)) {
//                    //再次验证cache系统access_token是否失效
//                    Map<String,Object> map = userAuth.getUserFullInfoByAccessToken(accessToken);
//                    logger.error("----/wx/login getUserFullInfoByAccessToken map:"+map);
//
//                    if(map!=null) {
//                        ResultData resultData = new ResultData();
//                        resultData.setCode(1000);
//                        Map<String,Object> data = Maps.newHashMap();
//                        data.put("accessToken",accessToken);
//                        data.put("openId",openId);
//
//                        resultData.setData(data);
//                        model.addAttribute("resultData",resultData);
//                        logger.error("----/wx/login value in model:"+openId);
//                        return "index";//  换成商城首页
//                    }
//                }
//            }
//            response.setContentType("text/html; charset = utf-8");
//            request.getSession();//增加这行代码用来解决session
//            logger.error("----/wx/login goto wechart authurl!");
////            response.sendRedirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx191292d175b76f6d&redirect_uri=http%3a%2f%2fb.myangcang.com%2fyangcangclub%2fv1%2fuser%2fwx%2fcallback&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect");
//            String path = request.getContextPath();
//            String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
//            String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx191292d175b76f6d&redirect_uri=http%3a%2f%2fb.yangcangclub.com%2fyangcangclub%2fv1%2fuser%2fwx%2fcallback&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
////            String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx6e1640c9e5b72719&redirect_uri=http%3a%2f%2f192.168.0.57%3a8080%2fyangcangclub%2fv1%2fuser%2fwx%2fcallback&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
//            response.sendRedirect(url);
//        } catch (IOException e) {
//            //ig
//            logger.error("wxLogin--"+e.getMessage());
//        }
//        return "index";
    }

    @RequestMapping(value = "/wx/callback", method = {RequestMethod.GET})
    public String wxTologinCallback(@RequestParam String code,@RequestParam String state,
                                    HttpServletRequest request,
                                    HttpServletResponse response,
                                    HttpSession httpSession,
                                    Model model) {
        String path = request.getContextPath();
        String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
        String errorMsg = "";
        String userId = "";
        String openId = "";
        String buzAccessToken = "";
        logger.error("----/wx/callback coming code and state:"+code +"--"+ state);

        if(StringUtils.isNotEmpty(code)
                && StringUtils.isNotEmpty(state)) {
//            String appid = "wx191292d175b76f6d";
//            String secret = "5814eaf4b4cc1eda20326a708875b400";
            String appid = sysConfig.getWxappid();
            String secret = sysConfig.getWxsecret();
            Map<String,Object> wxUserInfo = getWxUserInfo(code,state,appid,secret);
            logger.error("----/wx/callback get getWxUserInfo");

            if(wxUserInfo.size()>0) {
//                String buzThridLogin = "http://192.168.0.89/traveler99/v1/user/third";
                openId = (String)wxUserInfo.get("openid");
                String buzThridLogin = sysConfig.getAjaxUrlHead()+"/user/third";
                Map<String,String>map= Maps.newHashMap();
                map.put("access_token",(String)wxUserInfo.get("access_token"));
                map.put("openid",(String)wxUserInfo.get("openid"));
                map.put("type","1");
                logger.error("----/wx/callback get getWxUserInfo openid:"+wxUserInfo.get("openid"));

                JSONObject jsonObject =HttpUtils.doJsonGet(buzThridLogin, map);
                int buzCode = (int)jsonObject.get("code");
                logger.error("----/wx/callback buzThridLogin buzCode:"+buzCode);

                if(buzCode==1000) {
                    Map<String,String> data=(Map<String,String>)jsonObject.get("data");
                    buzAccessToken = (String)data.get("access_token");
                    String firstLogin = (String)data.get("is_first_login");
                    userId = (String)data.get("userId");
                    if(StringUtil.isEquals(firstLogin,"Y")) {
//                        String buzUpdateUserInfo = "http://192.168.0.89/traveler99/v1/user/update";
                        String buzUpdateUserInfo = sysConfig.getAjaxUrlHead()+"/user/update";
                        Map<String,String>param= Maps.newHashMap();
                        param.put("access_token",buzAccessToken);
                        if(StringUtil.isNotEmpty((String)wxUserInfo.get("nickname"))) {
                            param.put("name",(String)wxUserInfo.get("nickname"));
                        }
                        if(StringUtil.isNotEmpty((String)wxUserInfo.get("nickname"))) {
                            param.put("nickname",(String)wxUserInfo.get("nickname"));
                        }
                        if(StringUtil.isNotEmpty((String)wxUserInfo.get("headimgurl"))) {
                            param.put("photo",(String)wxUserInfo.get("headimgurl"));
                        }
                        if(null!=wxUserInfo.get("sex")) {
                            param.put("sex",wxUserInfo.get("sex")+"");
                        }
                        //todo 待验证
                        param.put("system_from","2");// 蛋卡系统
                        param.put("user_mark","2");// 关注用户
                        HttpUtils.doJsonGet(buzUpdateUserInfo, param);
                    }
                    logger.error("----/wx/callback self  buzAccessToken:"+buzAccessToken);
                    logger.error("----/wx/callback self  openId:"+openId);

                    Cookie cookie = new Cookie("WX_TICKET_COOKIE_KEY", buzAccessToken);
                    Cookie cookie2 = new Cookie("WX_OPENID_COOKIE_KEY", openId);
                    cookie.setMaxAge(60);//缓存1分钟
                    cookie2.setMaxAge(60);//缓存1分钟
                    response.addCookie(cookie);
                    response.addCookie(cookie2);
                } else {
                    errorMsg = "系统自动注册用户失败";
                    logger.error("----/wx/callback  系统自动注册用户失败:");
                }
            } else {
                errorMsg = "没有获取到微信用户信息";                    
                logger.error("----/wx/callback  没有获取到微信用户信息:");
            }
        }else {
            errorMsg = "与微信交互参数异常";
            logger.error("----/wx/callback  与微信交互参数异常:");
        }

        ResultData resultData = new ResultData();
        resultData.setCode(1000);
        if(StringUtil.isNotEmpty(errorMsg)) {
            resultData.setCode(9999);
            resultData.setMsg(errorMsg);
        }
        Map<String,Object> data = Maps.newHashMap();
        data.put("openId",openId);
        data.put("accessToken",buzAccessToken);
        logger.error("----/wx/callback resultData value:"+openId);

        resultData.setData(data);
        model.addAttribute("resultData",resultData);
        return "index";
    }

    private Map<String,Object> getWxUserInfo(String code,String state,String appid,String secret) {
        //TODO load data per request?
        Map<String,Object>data= Maps.newHashMap();
        //https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxd9dd6a4f3e83a91f&secret=cfbc007ef8830b8682e59e3bb361cac4&code=0319b40b78a9bc6da41c80875e462d6I&grant_type=authorization_code
        //https://api.weixin.qq.com/sns/userinfo?access_token=OezXcEiiBSKSxW0eoylIeHHmvfvPBvGwX_mncSjrXVBpI_Bcl6fLEK9aCTpXhlUqkJXtik2h30oSgN69gtt916aAcyMz2XmqAGddVRcTdvpXl9NORc9-AXjOd6B-sHVtYo6ngL8d2m9lTpW1CAPmvA&openid=oq-1Swou47QTb87BrZULGyulvTPQ
        //https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
        String requestAccessToken_url = "https://api.weixin.qq.com/sns/oauth2/access_token";
        Map<String,String>map= Maps.newHashMap();
        map.put("appid",appid);
        map.put("secret",secret);
        map.put("code",code);
        map.put("grant_type","authorization_code");
        logger.error("----/getWxUserInfo coming code:"+code);

        JSONObject jsonObject =HttpUtils.doJsonGet(requestAccessToken_url, map);
        logger.error("----/getWxUserInfo requestAccessToken_url:"+JSONObject.toJSONString(jsonObject));

        if(jsonObject.get("errcode") == null) {
            String access_token = (String)jsonObject.get("access_token");
            String openid = (String)jsonObject.get("openid");
            map.clear();
            String requestWxInfo_url = "https://api.weixin.qq.com/sns/userinfo";
            map.put("access_token",access_token);
            map.put("openid",openid);
            map.put("lang","zh_CN");
            logger.error("----/getWxUserInfo requestAccessToken_url access_token:"+access_token);

            JSONObject infoJsonObject =HttpUtils.doJsonGet(requestWxInfo_url, map);
//           String wxJson =  "{openid: \"o69NWxDS9tv59E13OzoYTq37mnMs\",nickname: \"周镇怀\",sex: 1,language: \"zh_CN\",city: \"朝阳\",province: \"北京\",country: \"中国\",headimgurl: \"http://wx.qlogo.cn/mmopen/ajNVdqHZLLBfWspkT48EInuSJtx8B3fUVicHJaxibsXwsuV1qtLmYApHCRPicVLnpNZ3t9P3vDU28j1sglhS1BibcA/0\",privilege: [ ]}";
//            JSONObject infoJsonObject = (JSONObject) JsonUtils.parseObject(wxJson, JSONObject.class);
            logger.error("----/getWxUserInfo requestWxInfo_url:"+JSONObject.toJSONString(infoJsonObject));

            if(infoJsonObject.get("errcode") == null) {
                String nickname = EmojiFilterUtil.filterEmoji((String)infoJsonObject.get("nickname"));
                int sex = (int)infoJsonObject.get("sex");
                String province = (String)infoJsonObject.get("province");
                String city = (String)infoJsonObject.get("city");
                String country = (String)infoJsonObject.get("country");
                String headimgurl = (String)infoJsonObject.get("headimgurl");
//                String unionid = (String)infoJsonObject.get("unionid");
                data.put("access_token", access_token);
                data.put("openid", openid);
//                data.put("unionid", unionid);
                data.put("nickname", nickname);
                data.put("sex", sex);
                data.put("province",province);
                data.put("city",city);
                data.put("country",country);
                data.put("headimgurl",headimgurl);
            }
        }
        logger.error("----/getWxUserInfo return  data:"+JSONObject.toJSONString(data));

        return data;
    }
    @RequestMapping(value = "/cgibin", method = {RequestMethod.GET})//获取code
    public String cgiBin(HttpServletRequest request, HttpServletResponse response,Model model,
                         @RequestParam(required=false,defaultValue = "") String url) throws Exception {
        try {
            Cookie[] cookies = request.getCookies();
            if(cookies != null) {
                String accessToken = null;
                String openId = null;
                for (int i = 0; i < cookies.length; i++) {
                    Cookie cookie = cookies[i];
                    if(StringUtil.isNotEmpty(accessToken)
                            &&StringUtil.isNotEmpty(openId)) {
                        break;
                    }
                    if ("WX_TICKET_COOKIE_KEY".equals(cookie.getName())) {
                        accessToken = cookie.getValue();
                    }
                    if ("WX_OPENID_COOKIE_KEY".equals(cookie.getName())) {
                        openId = cookie.getValue();
                    }
                }
                if(StringUtil.isNotEmpty(accessToken)
                        &&StringUtil.isNotEmpty(openId)) {
                    //再次验证cache系统access_token是否失效
                    Map<String,Object> map = userAuth.getUserFullInfoByAccessToken(accessToken);
                    logger.error("----/wx/login getUserFullInfoByAccessToken map:"+map);

                    if(map!=null) {
                        ResultData resultData = new ResultData();
                        resultData.setCode(1000);
                        Map<String,Object> data = Maps.newHashMap();
                        data.put("accessToken",accessToken);
                        data.put("openId",openId);
                        resultData.setData(data);
                        model.addAttribute("resultData",resultData);
                        return "index";//  换成商城首页
                    }
                }
            }
            response.setContentType("text/html; charset = utf-8");
            request.getSession();//增加这行代码用来解决session
            String baseUrl = WeChatConfig.AUTHOR_URL;
            String finUrl = "?appid="+sysConfig.getWechatWebAppId()+"&redirect_uri="+ URLEncoder.encode(sysConfig.getYccHostUrl()+"/yangcangclub/v1/user/cgibinuserinfo?url="+url, "utf-8")+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
            response.sendRedirect(baseUrl+finUrl);
        } catch (IOException e) {
            //ig
            logger.error("wxLogin--"+e.getMessage());
        }
        return "index";
    }

    @RequestMapping(value = "/cgibinuserinfo", method = {RequestMethod.GET})//获取用户信息
    public String cgiBinUserInfo(@RequestParam String code,@RequestParam String state,
                                 HttpServletRequest request,
                                 HttpServletResponse response,
                                 HttpSession httpSession,
                                 Model model,@RequestParam(required=false,defaultValue = "") String url) throws Exception {

        String errorMsg = "";
        String userId = "";
        String openId = "";
        String buzAccessToken = "";
        if(StringUtils.isNotEmpty(code)
                && StringUtils.isNotEmpty(state)) {
            String appid = sysConfig.getWechatWebAppId();
            String secret = sysConfig.getWechatWebAppSecret();
            Map<String,Object> wxUserInfo = getWxUserInfo(code,state,appid,secret);
            if(wxUserInfo.size()>0) {
                openId = (String)wxUserInfo.get("openid");
                String buzThridLogin = sysConfig.getAjaxUrlHead()+"/user/third";
                Map<String,String>map= Maps.newHashMap();
                map.put("access_token",(String)wxUserInfo.get("access_token"));
                map.put("openid",(String)wxUserInfo.get("openid"));
                map.put("type","1");
                JSONObject jsonObject =HttpUtils.doJsonGet(buzThridLogin, map);
                int buzCode = (int)jsonObject.get("code");
                if(buzCode==1000) {
                    Map<String,String> data=(Map<String,String>)jsonObject.get("data");
                    buzAccessToken = (String)data.get("access_token");
                    String firstLogin = (String)data.get("is_first_login");
                    userId = (String)data.get("userId");
                    if(StringUtil.isEquals(firstLogin,"Y")) {
                        String buzUpdateUserInfo = sysConfig.getAjaxUrlHead()+"/user/update";
                        Map<String,String>param= Maps.newHashMap();
                        param.put("access_token",buzAccessToken);
                        if(StringUtil.isNotEmpty((String)wxUserInfo.get("nickname"))) {
                            param.put("name",(String)wxUserInfo.get("nickname"));
                        }
                        if(StringUtil.isNotEmpty((String)wxUserInfo.get("nickname"))) {
                            param.put("nickname",(String)wxUserInfo.get("nickname"));
                        }
                        if(StringUtil.isNotEmpty((String)wxUserInfo.get("headimgurl"))) {
                            param.put("photo",(String)wxUserInfo.get("headimgurl"));
                        }
                        if(null!=wxUserInfo.get("sex")) {
                            param.put("sex",wxUserInfo.get("sex")+"");
                        }
                        //todo 待验证
                        param.put("system_from","2");// 蛋卡系统
                        param.put("user_mark","2");// 关注用户
                        HttpUtils.doJsonGet(buzUpdateUserInfo, param);
                    }
                    Cookie cookie = new Cookie("WX_TICKET_COOKIE_KEY", buzAccessToken);
                    Cookie cookie2 = new Cookie("WX_OPENID_COOKIE_KEY", openId);
                    cookie.setMaxAge(60);//缓存1分钟
                    cookie2.setMaxAge(60);//缓存1分钟
                    response.addCookie(cookie);
                    response.addCookie(cookie2);
                } else {
                    errorMsg = "系统自动注册用户失败";
                    logger.error("----/wx/callback  系统自动注册用户失败:");
                }
            } else {
                errorMsg = "没有获取到微信用户信息";
                logger.error("----/wx/callback  没有获取到微信用户信息:");
            }
        }else {
            errorMsg = "与微信交互参数异常";
            logger.error("----/wx/callback  与微信交互参数异常:");
        }
        BoundValueOperations access_token_bvo = redisTemplate.boundValueOps("wechat.access_token");
        String access_token = "";
        if(access_token_bvo.setIfAbsent(1)) {
            String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+sysConfig.getWechatWebAppId()+"&secret="+sysConfig.getWechatWebAppSecret();
            JSONObject jsonObject = HttpUtils.doJsonGet(tokenUrl, null);
            access_token_bvo.set(jsonObject.get("access_token"),120, TimeUnit.MINUTES);//7200秒
            access_token = jsonObject.get("access_token").toString();
        }else{
            access_token = redisTemplate.boundValueOps("wechat.access_token").get().toString();
        }
        Map requestMap = Maps.newHashMap();
        requestMap.put("access_token",access_token);
        requestMap.put("openid",openId);
        requestMap.put("lang","zh_CN");
        String userInfoJson= HttpUtils.doGet(WeChatConfig.USERINFO_URL_BASE,requestMap);
        logger.error("get wechat userinfo is : "+ userInfoJson.toString());
        JSONObject userInfoJO=JSONObject.parseObject(userInfoJson);
        String subscribe=userInfoJO.getString("subscribe");

        ResultData resultData = new ResultData();
        resultData.setCode(1000);
        if(StringUtil.isNotEmpty(errorMsg)) {
            resultData.setCode(9999);
            resultData.setMsg(errorMsg);
        }
        Map<String,Object> data = Maps.newHashMap();
        data.put("openId",openId);
        data.put("accessToken",buzAccessToken);
        data.put("subscribe",subscribe);
        logger.error("----/wx/callback resultData value:"+openId);

        resultData.setData(data);
        model.addAttribute("resultData",resultData);
        if(StringUtil.isNotEmpty(url)){
            return "redirect:"+url+"?openid="+openId+"&accessToken="+buzAccessToken+"&subscribe="+subscribe;
        }else{
            return "index";
        }
    }

}

